package com.kl.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.kl.domain.UserDTO;
import com.kl.entity.SeckillCoupon;
import com.kl.mapper.SeckillCouponMapper;
import com.kl.service.ISeckillCouponService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author author
 * @since 2021-10-30
 */
@Service
public class SeckillCouponServiceImpl extends ServiceImpl<SeckillCouponMapper, SeckillCoupon> implements ISeckillCouponService {

    @Resource
    private SeckillCouponMapper seckillCouponMapper;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private RocketMQTemplate rocketMQTemplate;

    //获取符合条件的订单
    @Override
    public List<SeckillCoupon> selectSeckillCouponList() {

        redisTemplate.setValueSerializer(new StringRedisSerializer());

        SimpleDateFormat sdf = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
        String startTimeFormat = sdf.format(new Date());

       /*  QueryWrapper<SeckillCoupon> query = Wrappers.<SeckillCoupon>query();
             query.gt("coupon_count",0)
                 .eq("status",1)//yyyy-MM-dd HH:mm:ss
                .apply("date_format(statr_time,'%Y-%m-%d %H:%m:%s')<{0}",startTimeFormat)
                .apply("date_format(end_time,'%Y-%m-%d %H:%m:%s')>{0}",startTimeFormat);*/

        LambdaQueryWrapper<SeckillCoupon> lambdaQuery = Wrappers.<SeckillCoupon>lambdaQuery();
        lambdaQuery.gt(SeckillCoupon::getCouponCount,0)
                .eq(SeckillCoupon::getStatus,1)
                .lt(SeckillCoupon::getStatrTime,startTimeFormat)
                .gt(SeckillCoupon::getEndTime,startTimeFormat);

        List<SeckillCoupon> seckillCoupons = seckillCouponMapper.selectList(lambdaQuery);

        List<SeckillCoupon> redisseckillCoupons = new ArrayList<>();
        for (SeckillCoupon coupon : seckillCoupons) {

            if (redisTemplate.boundHashOps("kl_SeckillCoupon").hasKey(coupon.getSeckillCouponId())){

                redisseckillCoupons.add((SeckillCoupon)redisTemplate.boundHashOps("kl_SeckillCoupon").get(coupon.getSeckillCouponId()));

            }else {

                redisTemplate.boundHashOps("kl_SeckillCoupon").put(coupon.getSeckillCouponId(),coupon);
                //秒杀预热
                redisTemplate.boundValueOps(coupon.getSeckillCouponId()).set(coupon.getCouponCount().toString());
            }
        }

        if (redisseckillCoupons.size() > 0){

            return redisseckillCoupons;
        }

        return seckillCoupons;
    }
    //订单
    @Override
    public void createOrder(Long id , UserDTO userDTO ) throws Exception {

        redisTemplate.setValueSerializer(new StringRedisSerializer());

        //seckkill_order 重复购买
        if (redisTemplate.boundHashOps("seckkill_order").hasKey(userDTO.getId())){
            Long seckillId = (Long)redisTemplate.boundHashOps("seckkill_order").get(userDTO.getId());
            if (seckillId == id){
                throw new Exception("已经买过了");
            }
        }
        //判断库存
        String count = (String)redisTemplate.boundValueOps(id).get();

        if (StringUtils.isBlank(count) || Integer.parseInt(count) <= 0 ){
            throw new Exception("卖完了");
        }
        //减库存
        Long decrement = redisTemplate.boundValueOps(id).decrement();

        //同步redis缓存
        SeckillCoupon coupon = (SeckillCoupon)redisTemplate.boundHashOps("kl_SeckillCoupon").get(id);
        coupon.setCouponCount(decrement.intValue());
        redisTemplate.boundHashOps("kl_SeckillCoupon").put(id,coupon);

        //库存小于0 删除
        if (decrement.intValue() <= 0){
            //删除redis缓存
            redisTemplate.boundHashOps("kl_SeckillCoupon").delete(id);
            //同步数据库
            seckillCouponMapper.updateById(coupon);
        }

        //创建订单  单独创建 通过mq异步下单
        Map<String,Object> map = new HashMap();
        map.put("seckillID",id);
        map.put("user",userDTO);

        //发送mq消息生成订单
        rocketMQTemplate.convertAndSend("seckill_topic",map);

    }
}
